package lk.icta.core.web.action;

import lk.icta.common.AppConstants;
import lk.icta.common.dao.DSDivisionDAO;
import lk.icta.common.dao.DistrictDAO;
import lk.icta.common.dao.GNDivisionDAO;
import lk.icta.common.entity.DSDivision;
import lk.icta.common.entity.Document;
import lk.icta.common.entity.GNDivision;
import lk.icta.common.service.DocumentManagementService;
import lk.icta.common.web.action.DocumentUploadAction;
import lk.icta.core.dto.MapDetails;
import lk.icta.core.entity.*;
import lk.icta.core.service.AlienationManagementService;
import lk.icta.core.service.KachcheryManagementService;
import lk.icta.core.service.LandAssociationManagementService;
import lk.icta.core.service.LandManagementService;
import lk.icta.user.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class LandAssociationAction extends DocumentUploadAction {
    private static final Logger logger = LoggerFactory.getLogger(AlienationAction.class);

    //TODO: move AM realted code to alienation method service
    private final AlienationManagementService alienationManagementService;
    private final LandManagementService landManagementService;
    private final LandAssociationManagementService landAssociationManagementService;
    private final KachcheryManagementService kachcheryManagementService;

    private final DistrictDAO districtDAO;
    private final DSDivisionDAO dsDivisionDAO;
    private final GNDivisionDAO gnDivisionDAO;
    private LandAssociation landAssociation;
    private Land land;

    private int alienationMethod;
    private List<AlienationMethod> alienationMethods;
    private Map<Integer, String> approvedAssociatedAlienationMethodsList;

    /*Permit-0  Land Grants=1 Short Term Lease =2 Long Term Lease =3
* Releasing To Department=4 Vesting Order=5  Ought Right Grant =6 */
    private int alienationType;
    private Map<Integer, String> alienationMethodList;
    private List<LandAssociation> landAssociationList;
    private List<Alienation> alienationList;
    /*Edit Mode =1  non edit mode =0 */
    private int editMode;

    private Map<Integer, String> districtList;
    private Map<Integer, String> dsDivisionList;
    private Map<Integer, String> gnDivisionList;
    private Map<Integer, String> alienationTypeList;

    private long landId;
    private long metadataId;
    private int id;

    private String districtName;
    private String dsDivisionName;

    private String associationComment;

    private String gnDivisionName;
    private String localAuthorityName;
    private String geologicalType;
    private Double hectare;
    private String alienationMethodName;

    private Map<Integer, String> alienationMethodSet;
    private String[] alienationMethodSelectedList;
    private Map<Integer, String> amSelectedList;
    private List<Land> landList;
    private int dsDivisionId;
    private int districtId;

    private long[] landKachcheryList;
    private long[] amPermitList;
    private long[] amGrantList;
    private long[] amSTLList;
    private long[] amLTLList;
    private long[] amRDList;
    private long[] amVOList;
    private long[] amSPList;
    private Kachchery kachchery;
    private int kachcheryMode;

    private String comment;

    private List<Long> associationIdLandList = new ArrayList<Long>();

    private Map<Long, List<MapDetails>> mapDetailMap;


    public LandAssociationAction(DocumentManagementService documentManagementService,
                                 AlienationManagementService alienationManagementService,
                                 LandManagementService landManagementService,
                                 DistrictDAO districtDAO,
                                 DSDivisionDAO dsDivisionDAO,
                                 GNDivisionDAO gnDivisionDAO,
                                 LandAssociationManagementService landAssociationManagementService,
                                 KachcheryManagementService kachcheryManagementService) {
        super(documentManagementService);
        this.alienationManagementService = alienationManagementService;
        this.landManagementService = landManagementService;
        this.districtDAO = districtDAO;
        this.dsDivisionDAO = dsDivisionDAO;
        this.gnDivisionDAO = gnDivisionDAO;
        this.landAssociationManagementService = landAssociationManagementService;
        this.kachcheryManagementService = kachcheryManagementService;
        //  this.userManager = userManager;
        logger.debug("edit mode is {}", editMode);
    }

    public String pageLoad() {
        return SUCCESS;
    }

    public String loadKachcheriListReport() {
        kachcheryMode = AppConstants.KACHCHERY_ATTACH_DOC;
        return SUCCESS;
    }

    public String pageLoadKachcheryReject() {
        kachcheryMode = AppConstants.KACHCHERY_REJECT;
        return SUCCESS;
    }

    public String pageLoadKachcheryAttachDoc() {
        kachcheryMode = AppConstants.KACHCHERY_ATTACH_DOC;
        return SUCCESS;
    }


    public String loadLandAssociation() {

        try {
            land = landManagementService.getLandById(landId);
            alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);

            alienationMethodSet = new HashMap<Integer, String>();
            for (int i = 1; i <= alienationMethodList.size(); i++) {
                alienationMethodSet.put(i, alienationMethodList.get(i));
            }

            landAssociation = landAssociationManagementService.getAlienationMethodMetadataByLand(landId, user);

            if (landAssociation != null && landAssociation.getAlienationMethods() != null) {

                List<AlienationMethod> amList = landAssociation.getAlienationMethods();
                approvedAssociatedAlienationMethodsList = new HashMap<Integer, String>();

                for (AlienationMethod am : amList) {
                    int id = am.getId();
                    String english = am.getEnName();
                    String sinhala = am.getSiName();
                    String tamil = am.getTaName();

                    if (language.equals(AppConstants.ENGLISH)) {
                        approvedAssociatedAlienationMethodsList.put(id, english);
                    } else if (language.equals(AppConstants.SINHALA)) {
                        approvedAssociatedAlienationMethodsList.put(id, sinhala);
                    } else if (language.equals(AppConstants.TAMIL)) {
                        approvedAssociatedAlienationMethodsList.put(id, tamil);
                    }
                }
            }


            if (landAssociation != null) {

                if (landAssociation.getAlienationMethod() != null) {
                    alienationMethod = landAssociation.getAlienationMethod().getId();

                }
                if (landAssociation.getAlienationMethods() != null) {
                    alienationMethods = landAssociation.getAlienationMethods();

                    populateAlienationMethodIds();

                }

                if (user.getRole().getId().equals(AppConstants.ORDS_USER_ROLE)) {
                    editMode = 2;
                } /*else if (landAssociation.getApprovalState() == LandAssociation.ApprovalState.DATA_ENTRY) {
                    editMode = 1;
                }*/

            }

            viewLandDetails();
            findDocumentCategoryList(ModuleType.OTHER);
            if (landAssociation != null) {
                populateUploadedFiles(landAssociation.getId(), ModuleType.LAND_ASSOCIATION);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String addLandAssociationForDefineAM() {
        logger.debug("Add Land Association ForDefineAM :{} {}", land.getId(), editMode);
        loadLandList();
        try {
            LandAssociation metadata = landAssociation;
            landAssociation = landAssociationManagementService.getAlienationMethodMetadataByLand(land.getId(), user);

            if (landAssociation != null) {
                List<Document> docs = getUploadedfileList(ModuleType.LAND_ASSOCIATION);
                landAssociationManagementService.updateLandAssociationForDefineAM(alienationMethod, docs, metadata, land, deleteDocList, user);
            }
            //todo: Following commented but not removed if in case an there can a use case of else at defineAM
           /* else {

                landAssociation = new LandAssociation();
                landAssociation.setLand(land);
                landAssociation.setAlienationMethod(alienationManagementService.getAlienationMethodById(alienationMethod, user));

                //delete documents
                deleteDocument();
                landAssociation.setDocumentList(getUploadedfileList(ModuleType.OTHER));
                landAssociationManagementService.addLandAlienationMetadata(landAssociation,land.getId(), true, user);
            }*/
            addActionMessage(getText("land_association_saved_successfully.label"));
            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error :{}", e);
            addActionError(getText("land_association_defineAM_failed.label"));
            return ERROR;
        }
    }

    public String addLandAssociation() {
        logger.debug("Add Land Association :{} {}", land.getId(), editMode);
        loadLandList();
        try {
            LandAssociation metadata = landAssociation;
            landAssociation = landAssociationManagementService.getAlienationMethodMetadataByLand(land.getId(), user);

            if (landAssociation != null) {

                landAssociation.setLand(land);
                landAssociation.setAlienationMethods(populateAlienationMethods());
                landAssociation.setPurpose(metadata.getPurpose());
                //delete documents
                deleteDocument();
                landAssociation.setDocumentList(getUploadedfileList(ModuleType.LAND_ASSOCIATION));
                landAssociationManagementService.updateLandAlienationMetadata(landAssociation,land.getId(), false, user);

            } else {
                //Save New
                landAssociation = new LandAssociation();
                landAssociation.setLand(land);
                landAssociation.setAlienationMethods(populateAlienationMethods());
                landAssociation.setPurpose(metadata.getPurpose());
                //delete documents
                deleteDocument();
                landAssociation.setDocumentList(getUploadedfileList(ModuleType.LAND_ASSOCIATION));
                landAssociationManagementService.addLandAlienationMetadata(landAssociation,land.getId(), false, user);
            }


        } catch (Exception e) {
            logger.error("Error :{}", e);
        }
        addActionMessage(getText("land_association_saved_successfully.label"));
        return SUCCESS;
    }

    private List<AlienationMethod> populateAlienationMethods() {
        logger.debug("populating AM List");
        List<AlienationMethod> amList = new ArrayList<AlienationMethod>();
        if (alienationMethodSelectedList != null) {
            for (String am : alienationMethodSelectedList) {
                //TODO : get from service
                logger.debug("AM ID {} ", am);
                amList.add(alienationManagementService.getAlienationMethodById(Integer.parseInt(am), user));
            }
        }
        return amList;
    }

    private void populateAlienationMethodIds() {
        logger.debug("populating AM List");

        amSelectedList = new HashMap<Integer, String>();

        if (alienationMethods != null && alienationMethods.size() != 0) {

            for (AlienationMethod am : alienationMethods) {

                logger.debug("AM array  - id {} ", am.getId());

                //TODO Find by language
                amSelectedList.put(am.getId(), am.getEnName());
            }
        }
    }

    public String editLandAssociation() {
        editMode = 1;
        land = landManagementService.getLandById(landId);
        alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);
        landAssociation = landAssociationManagementService.getAlienationMethodMetadataById(metadataId, user);
        alienationMethod = landAssociation.getAlienationMethod().getId();
        populateUploadedFiles(metadataId, ModuleType.OTHER);
        viewLandDetails();
        findDocumentCategoryList(ModuleType.OTHER);
        return SUCCESS;
    }

    public String initApproveLandAssociation() {
        editMode = 2;
        land = landManagementService.getLandById(landId);
        alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);
        landAssociation = landAssociationManagementService.getAlienationMethodMetadataById(metadataId, user);
        alienationMethod = landAssociation.getAlienationMethod().getId();
        viewLandDetails();
        populateUploadedFiles(metadataId, ModuleType.OTHER);
        return SUCCESS;
    }

    public String approveLandAssociation() {

        try {
            loadLandList();
            metadataId = landAssociation.getId();
            associationComment = landAssociation.getAssociationComment();
            landAssociationManagementService.approveLandAlienationMetadata(metadataId, associationComment, user, land.getId());

        } catch (Exception e) {
            logger.error("Error :{}", e);
            e.printStackTrace();
        }
        addActionMessage(getText("land_association_approved_successfully.label"));
        return SUCCESS;
    }

    public String approveLandAssociationForDefineAM() {
        loadLandList();
        try {
            metadataId = landAssociation.getId();
            associationComment = landAssociation.getDefineComment();
           // long version = landAssociation.getVersion();
            landAssociationManagementService.approveLandAlienationMetadataForDefineAM(metadataId, associationComment, user, landAssociation);
            addActionMessage(getText("land_defineAM_approved_successfully.label"));
            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error :{}", e);
            addActionError(getText("land_defineAM_approval_failed.label"));
            return ERROR;
        }
     }

    public String rejectLandAssociation() {
        loadLandList();
        try {
            metadataId = landAssociation.getId();
            associationComment = landAssociation.getAssociationComment();
            landAssociationManagementService.rejectLandAlienationMetadata(metadataId, associationComment, false, user, land.getId(), landAssociation);
            GNDivision GNDiv = landManagementService.getLandById(land.getId()).getGnDivision();
            addActionMessage(getText("land_association_rejected_successfully.label"));
        } catch (Exception e) {
            logger.error("Error :{}", e);
            addActionError(getText("land_association_rejection_unsuccessful.label"));
        }

        return SUCCESS;
    }

    public String rejectLandAssociationForDefineAM() {
        loadLandList();
        try {
            metadataId = landAssociation.getId();
            associationComment = landAssociation.getDefineComment();
            landAssociationManagementService.rejectLandAlienationMetadata(metadataId, associationComment, true, user, land.getId(), landAssociation);
            addActionMessage(getText("land_association_rejected_successfully.label"));
        } catch (Exception e) {
            logger.error("Error :{}", e);
            addActionError(getText("land_association_rejection_unsuccessful.label"));
        }

        return SUCCESS;
    }


    public String initViewAssociationList() {
        editMode = 3;
        alienationTypeList = alienationManagementService.getAllAlienationMethods(language, user);
        return SUCCESS;
    }

    public String viewLandAssociation() {
        logger.debug("Searching Associated Lands : {}", alienationType);
        try {

            landAssociationList = landAssociationManagementService.getAllAlienationMethodMetadataByAlienationMethod(alienationType, user);
            if (landAssociationList == null) {
                landAssociationList = new ArrayList<LandAssociation>();
            }
        } catch (Exception e) {
            logger.debug("Error : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String viewLandAssociationDetails() {
        editMode = 4;
        land = landManagementService.getLandById(landId);
        landAssociation = landAssociationManagementService.getAlienationMethodMetadataById(metadataId, user);
        alienationMethod = landAssociation.getAlienationMethod().getId();
        if (language.equals(AppConstants.ENGLISH)) {
            alienationMethodName = landAssociation.getAlienationMethod().getEnName();
        } else if (language.equals(AppConstants.SINHALA)) {
            alienationMethodName = landAssociation.getAlienationMethod().getSiName();
        } else if (language.equals(AppConstants.TAMIL)) {
            alienationMethodName = landAssociation.getAlienationMethod().getTaName();
        }
        populateUploadedFiles(metadataId, ModuleType.OTHER);
        viewLandDetails();
        return SUCCESS;
    }

    public String viewLandDetails() {
        logger.debug("Land ID: {}", landId);
        land = landManagementService.getLandById(landId);
        GNDivision landGN = land.getGnDivision();
        if (AppConstants.ENGLISH.equals(language)) {
            dsDivisionName = landGN.getDsDivision().getEnDivisionName();
            districtName = landGN.getDsDivision().getDistrict().getEnDistrictName();
            if (land.getLocalAuthority() != null) {
                //  logger.debug("local authority type {} ", land.getLocalAuthority().getLocalAuthorityType().getId());
                //todo to be done
                //  localAuthorityName = land.getLocalAuthority().getLocalAuthorityType().getEnName();
            }
            if (land.getGeologicalType() != null) {
                geologicalType = land.getGeologicalType().getEnTypeName();
            }
            gnDivisionName = land.getGnDivision().getEnDivisionName();
        } else if (AppConstants.SINHALA.equals(language)) {
            dsDivisionName = landGN.getDsDivision().getSiDivisionName();
            districtName = landGN.getDsDivision().getDistrict().getSiDistrictName();
            if (land.getLocalAuthority() != null) {
                // localAuthorityName = land.getLocalAuthority().getLocalAuthorityType().getSiName();
            }
            if (land.getGeologicalType() != null) {
                geologicalType = land.getGeologicalType().getSiTypeName();
            }
            gnDivisionName = land.getGnDivision().getSiDivisionName();
        } else if (AppConstants.TAMIL.equals(language)) {
            dsDivisionName = landGN.getDsDivision().getTaDivisionName();
            districtName = landGN.getDsDivision().getDistrict().getTaDistrictName();
            if (land.getLocalAuthority() != null) {
                // localAuthorityName = land.getLocalAuthority().getLocalAuthorityType().getTaName();
            }
            if (land.getGeologicalType() != null) {
                geologicalType = land.getGeologicalType().getTaTypeName();
            }
            gnDivisionName = land.getGnDivision().getTaDivisionName();
        }
        hectare = land.getLandExtent();
        return SUCCESS;
    }

    public String loadLandList() {
        logger.debug("loading Land list page");
        try {
            //districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, language, user);
            if (userProvinceId > 0) {
                districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, language, user);
            } else {
                districtList = districtDAO.getAllDistrictNames(language, user);
            }

            dsDivisionList = new HashMap<Integer, String>();
            gnDivisionList = new HashMap<Integer, String>();

            if (user.getDsDivisions() != null && user.getDsDivisions().size() > 0
                      && !user.getRole().getId().equals(AppConstants.ORIP_USER_ROLE)) {
                DSDivision userDS = user.getDsDivisions().iterator().next();
                gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(userDS.getId(), language, user);

                if (AppConstants.ENGLISH.equals(language)) {
                    setDsDivisionName(userDS.getEnDivisionName());
                    setDistrictName(userDS.getDistrict().getEnDistrictName());
                } else if (AppConstants.SINHALA.equals(language)) {
                    setDsDivisionName(userDS.getSiDivisionName());
                    setDistrictName(userDS.getDistrict().getSiDistrictName());
                } else if (AppConstants.TAMIL.equals(language)) {
                    setDsDivisionName(userDS.getTaDivisionName());
                    setDistrictName(userDS.getDistrict().getTaDistrictName());
                }

            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String loadLandKachcheryHome() {
        logger.debug("loading Land Kachchery Home list page");
        try {
            loadLandList();
            alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);

            alienationMethodSet = new HashMap<Integer, String>();
            for (int i = 1; i <= alienationMethodList.size(); i++) {
                alienationMethodSet.put(i, alienationMethodList.get(i));
            }

            findDocumentCategoryList(ModuleType.OTHER);
            //populateUploadedFiles(kachchery.getId(), ModuleType.LAND_KACHCHERY);


        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String saveKachchery() {
        try {
            logger.debug("save Land Kachchery");
            String actionMsg = "";

            if (landKachcheryList == null || landKachcheryList.length < 1) {
                logger.error("No land has been selected for Associate");
                addActionError(getText("no_lands_selected_for_associate.label"));

                loadLandKachcheryHome();
                return SUCCESS;
            }


            if (user.getRole().getId().equals(AppConstants.LO_USER_ROLE)) {

                logger.debug("add Land Kachchery");

                if (kachchery == null || kachchery.getName() == null || kachchery.getName().length() == 0) {
                    logger.error("kachchery name not enter");
                    addActionError(getText("plase_enter_kachchery_name.label"));

                    loadLandKachcheryHome();
                    return SUCCESS;
                }

                kachchery.setDsDivision(user.getDsDivisions().iterator().next());
                kachchery.setStatus(Kachchery.Status.PENDING);
                kachchery.setKachcheryDate(new Date());
                setKachcheryComment(comment, AppConstants.ENTER, user);

                actionMsg = getText("land_kachchery_saved_successfully.label");


                if (kachcheryMode == AppConstants.KACHCHERY_REJECT) {

                    kachchery = kachcheryManagementService.getKachcheryById(id);
                    if (kachchery != null) {
                        kachchery.setStatus(Kachchery.Status.INACTIVE);
                        setKachcheryComment(comment, AppConstants.REJECTE, user);
                        actionMsg = getText("land_kachchery_reject_successfully.label");
                    }

                } else if (kachcheryMode == AppConstants.KACHCHERY_EDIT) {
                    kachchery = kachcheryManagementService.getKachcheryById(id);
                    if (kachchery != null) {
                        kachchery.setStatus(Kachchery.Status.PENDING);
                        setKachcheryComment(comment, AppConstants.ENTER, user);
                        actionMsg = getText("land_kachchery_edit_successfully.label");
                    }
                } else if (kachcheryMode == AppConstants.KACHCHERY_ATTACH_DOC) {
                    kachchery = kachcheryManagementService.getKachcheryById(id);
                    if (kachchery != null) {
                        kachchery.setStatus(Kachchery.Status.ATTACH_DOC_LO);
                        setKachcheryComment(comment, AppConstants.ENTER, user);
                        actionMsg = getText("land_kachchery_edit_successfully.label");
                    }
                }


            } else if (user.getRole().getId().equals(AppConstants.ORDS_USER_ROLE)) {

                kachchery = kachcheryManagementService.getKachcheryById(id);

                if (kachchery != null) {

                    if (kachcheryMode == AppConstants.KACHCHERY_APPROVE) {
                        kachchery.setStatus(Kachchery.Status.APPROVE_ORDS);
                        setKachcheryComment(comment, AppConstants.APPROVE, user);
                        actionMsg = getText("land_kachchery_approve_successfully.label");
                    } else if (kachcheryMode == AppConstants.KACHCHERY_REJECT) {
                        kachchery.setStatus(Kachchery.Status.REJECT_ORDS);
                        setKachcheryComment(comment, AppConstants.REJECTE, user);
                        actionMsg = getText("land_kachchery_reject_successfully.label");
                    }


                }


            } else if (user.getRole().getId().equals(AppConstants.PLC_USER_ROLE)) {

                kachchery = kachcheryManagementService.getKachcheryById(id);
                if (kachchery != null) {

                    if (kachcheryMode == AppConstants.KACHCHERY_APPROVE) {
                        kachchery.setStatus(Kachchery.Status.ACTIVE);
                        setKachcheryComment(comment, AppConstants.APPROVE, user);
                        actionMsg = getText("land_kachchery_approve_successfully.label");

                    } else if (kachcheryMode == AppConstants.KACHCHERY_REJECT) {
                        kachchery.setStatus(Kachchery.Status.REJECT_PLC);
                        setKachcheryComment(comment, AppConstants.REJECTE, user);
                        actionMsg = getText("land_kachchery_reject_successfully.label");

                    }


                }


            } else {
                logger.error("No Permition");
                addActionError(" doesn't have permission to manage Land Kachchery");

                loadLandKachcheryHome();
                return SUCCESS;
            }
            //set comment Field
            // kachchery.setComment(comment);
            //delete documents
            deleteDocument();
            kachchery.setDocumentList(getUploadedfileList(ModuleType.LAND_KACHCHERY));


            if (!addLandAssociationForKachchery()) {
                addActionError(getText("land_kachchery_saved_error.label"));
                loadLandKachcheryHome();
                return SUCCESS;
            } else {
                addActionMessage(actionMsg);
                loadLandKachcheryHome();
                kachchery = null;
                comment = "";
                return SUCCESS;
            }


        } catch (Exception e) {
            e.printStackTrace();
            addActionError(getText("land_kachchery_saved_error.label"));
            return ERROR;
        }
    }


    public String approveKachchery() {
        kachcheryMode = AppConstants.KACHCHERY_APPROVE;
        return saveKachchery();
    }

    public String rejectKachchery() {
        kachcheryMode = AppConstants.KACHCHERY_REJECT;
        return saveKachchery();
    }

    public String editKachchery() {
        kachcheryMode = AppConstants.KACHCHERY_EDIT;
        return saveKachchery();
    }

    public String attachDocKachchery() {
        /*kachcheryMode = AppConstants.KACHCHERY_ATTACH_DOC;
        return saveKachchery();*/

        try {
            kachcheryMode = AppConstants.KACHCHERY_ATTACH_DOC;
            logger.debug("attach Doc Land Kachchery");
            String actionMsg = "";

            if (landKachcheryList == null || landKachcheryList.length < 1) {
                logger.error("No land has been selected for Associate");
                addActionError(getText("no_lands_selected_for_associate.label"));

                loadLandKachcheryHome();
                return SUCCESS;
            }


            ///////////////////////////////
            if (user.getRole().getId().equals(AppConstants.LO_USER_ROLE)) {

                logger.debug("add Land Kachchery");


                if (kachcheryMode == AppConstants.KACHCHERY_ATTACH_DOC) {
                    Kachchery oldKachchery = kachcheryManagementService.getKachcheryById(id);
                    if (oldKachchery != null) {
                        oldKachchery.setStatus(Kachchery.Status.ATTACH_DOC_LO);
                        setKachcheryComment(comment, AppConstants.ENTER, user);

                        deleteDocument();
                        oldKachchery.setDocumentList(getUploadedfileList(ModuleType.LAND_KACHCHERY));

                        kachcheryManagementService.updateAttachDocKachchery(oldKachchery, user);

                        addActionMessage(getText("land_kachchery_attach_doc_successfully.label"));
                        loadLandKachcheryHome();
                        return SUCCESS;

                    } else {
                        addActionError(getText("land_kachchery_saved_error.label"));
                        loadLandKachcheryHome();
                        return ERROR;
                    }
                } else {
                    addActionError(getText("land_kachchery_saved_error.label"));
                    loadLandKachcheryHome();
                    return ERROR;
                }


            } else {
                logger.error("No Permition");
                addActionError(" doesn't have permission to manage Land Kachchery");

                loadLandKachcheryHome();
                return SUCCESS;
            }


        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            addActionError(getText("land_kachchery_saved_error.label"));
            loadLandKachcheryHome();
            return ERROR;
        }


    }


    public String viewKachcheryMap() {


        try {

            logger.debug("loadKachcheryMap By {}:", user.getRole().getName());

            kachchery = kachcheryManagementService.getKachcheryById(id);

            if (kachchery != null) {
                Set<LandAssociation> associationLandSet = kachchery.getLandAssociationList();
                Land land;

                mapDetailMap = new HashMap<Long, List<MapDetails>>();

                //for(Organization org : organizationsList){
                List<MapDetails> mapList = new ArrayList<MapDetails>();

                if (associationLandSet != null) {
                    Iterator<LandAssociation> associationIterator = associationLandSet.iterator();
                    while (associationIterator.hasNext()) {
                        LandAssociation association = associationIterator.next();
                        if (association != null) {

                            land = association.getLand();
                            if (land != null && land.getKmlString() != null && land.getKmlString().length() > 0) {

                                MapDetails mapDetails = new MapDetails();


                                mapDetails.setLandId(land.getId());
                                mapDetails.setReferenceNumber(land.getId() + " : " + land.getNameOfTheLand());

                                if (land.getKmlString() != null) {
                                    mapDetails.setKmlString(land.getKmlString());
                                }
                                if (land.getKmlMiddlePoint() != null) {
                                    mapDetails.setKmlMiddlePoint(land.getKmlMiddlePoint());
                                }
                                /*if (land.getKmlLandArea() != null) {
                                    mapDetails.setKmlLandArea(land.getKmlLandArea());
                                }*/


                                // mapDetails.setColorCode(colorCode);

                                mapList.add(mapDetails);
                                mapDetailMap.put(land.getId(), mapList);

                            }


                        }

                    }

                }
                logger.debug("\n \n List Size {}", mapList.size());
                logger.debug("\n \n goInfo Map Size : {}", mapDetailMap.size());

            }


            /*goInterestInformationList = goInterestManagementService.getGOInterestInformationListByOrganizationId(user);
            logger.debug("\n \n loadInterestMap List Size : {}", goInterestInformationList.size());

            mapDetailMap = new HashMap<Integer, List<MapDetails>>();

            //for(Organization org : organizationsList){
            List<MapDetails> mapList = new ArrayList<MapDetails>();
            int orgId = user.getOrganization().getId();
            String orgName = organisationManagementService.getOrganizationByIdUKey(orgId, user).getOrganizationNameEn();

            for (GOInterestInformation goInfo : goInterestInformationList) {

                if (orgId == goInfo.getOrganizationId()) {
                    //String colorCode="5000F014";
                    MapDetails mapDetails = new MapDetails();
                    mapDetails.setLandName(orgName);
                    mapDetails.setLandId(goInfo.getId());
                    mapDetails.setReferenceNumber(goInfo.getReferenceNumber());
                    mapDetails.setKmlString(goInfo.getKmlString());
                    mapDetails.setKmlMiddlePoint(goInfo.getKmlMiddlePoint());
                    mapDetails.setKmlLandArea(goInfo.getKmlLandArea());
                    // mapDetails.setColorCode(colorCode);

                    mapList.add(mapDetails);
                    mapDetailMap.put(orgId, mapList);
                }
            }*/


        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }


        return SUCCESS;
    }


    private void setKachcheryComment(String comment, String approveStr, User user) {
        if (comment == null) {
            comment = "";
        }

        if (kachchery.getComment() != null) {
            kachchery.setComment(kachchery.getComment() + "\n" + comment + "\n" + approveStr + " by :" + user.getUsername() + ", Date : " + new Date() + "\n");
        } else {
            kachchery.setComment(comment + "\n" + approveStr + " by :" + user.getUsername() + ", Date : " + new Date() + "\n");
        }

    }


    private boolean addLandAssociationForKachchery() {

        try {

            List<LandAssociation> landAssociationList = new ArrayList<LandAssociation>();


            for (long kachchceryId : landKachcheryList) {
                logger.debug("\nkachchceryId landId : {}", kachchceryId);
                Land associateLand = landManagementService.getLandByIdUKey(kachchceryId, user);


                logger.debug("Add Land Association by land :{} ", associateLand.getId());
                loadLandList();

                landAssociation = landAssociationManagementService.getAlienationMethodMetadataByLand(associateLand.getId(), user);

                if (landAssociation != null) {

                    landAssociation.setLand(associateLand);
                    landAssociation.setAlienationMethods(populateAlienationMethodsForKachchery(associateLand.getId()));


                } else {
                    //Save New
                    landAssociation = new LandAssociation();
                    landAssociation.setLand(associateLand);
                    landAssociation.setAlienationMethods(populateAlienationMethodsForKachchery(associateLand.getId()));

                }

                landAssociationList.add(landAssociation);
            }

            if (landAssociationList != null && landAssociationList.size() > 0) {

                //save the kachchery
                landAssociationManagementService.saveLandKachchery(landAssociationList, kachchery, user);

            } else {

                return false;
            }


        } catch (Exception e) {
            logger.error("Error :{}", e);
            return false;
        }
        return true;
    }


    private List<AlienationMethod> populateAlienationMethodsForKachchery(long landId) {
        logger.debug("populating AM List For Kachchery");

        List<AlienationMethod> amList = new ArrayList<AlienationMethod>();
        //permit
        if (amPermitList != null) {
            for (long id : amPermitList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.LAND_PERMIT, user));
                }
            }
        }

        //Grant
        if (amGrantList != null) {
            for (long id : amGrantList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.LAND_GRANT, user));
                }
            }
        }

        //Short Term
        if (amSTLList != null) {
            for (long id : amSTLList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.SHORT_TERM_LEASE, user));
                }
            }
        }

        //Long Term
        if (amLTLList != null) {
            for (long id : amLTLList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.LONG_TERM_LEASE, user));
                }
            }
        }

        //Department
        if (amRDList != null) {
            for (long id : amRDList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.RELEASING_TO_DEPARTMENTS, user));
                }
            }
        }

        //Vesting
        if (amVOList != null) {
            for (long id : amVOList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.VESTING_ORDER, user));
                }
            }
        }

        //Special
        if (amSPList != null) {
            for (long id : amSPList) {
                logger.debug("Land ID {} ", id);
                if (id == landId) {
                    amList.add(alienationManagementService.getAlienationMethodById(AppConstants.SPECIAL_GRANT, user));
                }
            }
        }


        return amList;
    }

    private void populateDistricts() {
        try {
            logger.debug("Populate District Lists by {}  province {}", user.getUsername(), userProvinceId);
            /*districtList = districtDAO.getAllDistrictNamesByProvinceId(1, user.getPrefLanguage(), user);
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(1, language, user);
            gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(1, user.getPrefLanguage(), user);*/

            //districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, user.getPrefLanguage(), user);
            if (userProvinceId > 0) {
                districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, language, user);
            } else {
                districtList = districtDAO.getAllDistrictNames(language, user);
            }
            /*dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(userDistrictId, language, user);
            gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(userDsId, user.getPrefLanguage(), user);*/

            dsDivisionList = new HashMap<Integer, String>();
            gnDivisionList = new HashMap<Integer, String>();


        } catch (Exception ex) {
            ex.printStackTrace();
            logger.debug("TryCatchError", ex.getMessage());
        }
    }


    public String loadDefineAMLandList() {
        logger.debug("Load all Define AM lands by {}", user.getUsername());
        try {
            logger.debug("Search Land  by {}", user.getUsername());
            logger.debug("alienation Method {}", alienationMethod);

            landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUser(user);
            //landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUserAndMethodId(alienationMethod,user);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }

        return SUCCESS;
    }

    public String loadDefineAMLandListByMethodId() {
        logger.debug("Load all Define AM lands by {}", user.getUsername());
        try {
            logger.debug("Search Land  by {}", user.getUsername());
            logger.debug("alienation Method {}", alienationMethod);

            //landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUser(user);
            landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUserAndMethodId(alienationMethod, user);
            alienationList = alienationManagementService.getPendingAlienationsByAlienationMethod(alienationMethod, user);
            for (Alienation a : alienationList) {
                logger.debug("alienation land id {}", a.getLand().getId());
            }


            if (landAssociationList != null && alienationList != null) {
                for (Alienation a : alienationList) {
                    for (int i = 0; i < landAssociationList.size(); ++i) {
                        if (a.getLand().getId() == landAssociationList.get(i).getLand().getId()) {
                            landAssociationList.remove(i);
                            //  break;
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }

        return SUCCESS;
    }

    public String loadDefineAMLandListByUpperLevel() {
        logger.debug("Load all Define AM lands Upper Level by {}", user.getUsername());
        try {
            logger.debug("Search Land  by {}", user.getUsername());
            //loadLandList();
            landAssociationList = new ArrayList<LandAssociation>();
            /*if (dsDivisionId != 0) {
                logger.debug("DS id {}", dsDivisionId);
                landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByDs(dsDivisionId, user);
            } else {
                landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUser(user);
            }*/

            if (dsDivisionId == 0) {
                if (districtId == 0) {
                    landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByUser(user);
                } else {
                    logger.debug("search By DistrictId {} ", districtId);
                    landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByDistrict(districtId, user);
                }

            } else {
                logger.debug("DS id {}", dsDivisionId);
                landAssociationList = landAssociationManagementService.getAllApprovedDefineAlienationMethodMetadataByDs(dsDivisionId, user);
            }
            populateDistricts();
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }

        return SUCCESS;
    }

    public String loadAssociationsByKachchery() {
        try {

            alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);

            alienationMethodSet = new HashMap<Integer, String>();
            for (int i = 1; i <= alienationMethodList.size(); i++) {
                alienationMethodSet.put(i, alienationMethodList.get(i));
            }

            kachchery = kachcheryManagementService.getKachcheryById(id);
            findDocumentCategoryList(ModuleType.OTHER);
            if (kachchery != null) {
                populateUploadedFiles(kachchery.getId(), ModuleType.LAND_KACHCHERY);

                if (kachchery.getStatus() == Kachchery.Status.APPROVE_ORDS) {
                    kachcheryMode = AppConstants.KACHCHERY_ATTACH_DOC;
                }
            }


            //alienationMethods = kachchery.getLandAssociationList().iterator().next().getAlienationMethods();
            // populateAlienationMethodIds();
            /*if(kachchery !=null){
               Set<LandAssociation>  =kachchery.LandAssociation.iterator();
               landAssociationSet.iterator()
            }*/

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        return SUCCESS;
    }

    public String landAssociationsByKachcheryReport() {
        try {
            kachchery = kachcheryManagementService.getKachcheryById(id);
            if (language.equals("si")) {
                dsDivisionName = kachchery.getDsDivision().getSiDivisionName();
            } else if (language.equals("en")) {
                dsDivisionName = kachchery.getDsDivision().getEnDivisionName();
            } else if (language.equals("ta")) {
                dsDivisionName = kachchery.getDsDivision().getTaDivisionName();
            }

            return SUCCESS;
        } catch (Exception ex) {
            ex.printStackTrace();
            return ERROR;
        }
    }

    public String getDistrictName() {
        return districtName;
    }

    public void setDistrictName(String districtName) {
        this.districtName = districtName;
    }

    public String getDsDivisionName() {
        return dsDivisionName;
    }

    public void setDsDivisionName(String dsDivisionName) {
        this.dsDivisionName = dsDivisionName;
    }

    public LandAssociation getLandAssociation() {
        return landAssociation;
    }

    public void setLandAssociation(LandAssociation landAssociation) {
        this.landAssociation = landAssociation;
    }

    public Land getLand() {
        return land;
    }

    public void setLand(Land land) {
        this.land = land;
    }

    public int getAlienationMethod() {
        return alienationMethod;
    }

    public void setAlienationMethod(int alienationMethod) {
        this.alienationMethod = alienationMethod;
    }

    public int getAlienationType() {
        return alienationType;
    }

    public void setAlienationType(int alienationType) {
        this.alienationType = alienationType;
    }

    public Map<Integer, String> getAlienationMethodList() {
        return alienationMethodList;
    }

    public void setAlienationMethodList(Map<Integer, String> alienationMethodList) {
        this.alienationMethodList = alienationMethodList;
    }

    public List<LandAssociation> getLandAssociationList() {
        return landAssociationList;
    }

    public void setLandAssociationList(List<LandAssociation> landAssociationList) {
        this.landAssociationList = landAssociationList;
    }

    public int getEditMode() {
        return editMode;
    }

    public void setEditMode(int editMode) {
        this.editMode = editMode;
    }

    public Map<Integer, String> getDistrictList() {
        return districtList;
    }

    public void setDistrictList(Map<Integer, String> districtList) {
        this.districtList = districtList;
    }

    public Map<Integer, String> getDsDivisionList() {
        return dsDivisionList;
    }

    public void setDsDivisionList(Map<Integer, String> dsDivisionList) {
        this.dsDivisionList = dsDivisionList;
    }

    public Map<Integer, String> getGnDivisionList() {
        return gnDivisionList;
    }

    public void setGnDivisionList(Map<Integer, String> gnDivisionList) {
        this.gnDivisionList = gnDivisionList;
    }

    public Map<Integer, String> getAlienationTypeList() {
        return alienationTypeList;
    }

    public void setAlienationTypeList(Map<Integer, String> alienationTypeList) {
        this.alienationTypeList = alienationTypeList;
    }

    public long getLandId() {
        return landId;
    }

    public void setLandId(long landId) {
        this.landId = landId;
    }

    public long getMetadataId() {
        return metadataId;
    }

    public void setMetadataId(long metadataId) {
        this.metadataId = metadataId;
    }

    public String getAssociationComment() {
        return associationComment;
    }

    public void setAssociationComment(String associationComment) {
        this.associationComment = associationComment;
    }

    public String getGnDivisionName() {
        return gnDivisionName;
    }

    public void setGnDivisionName(String gnDivisionName) {
        this.gnDivisionName = gnDivisionName;
    }

    public String getLocalAuthorityName() {
        return localAuthorityName;
    }

    public void setLocalAuthorityName(String localAuthorityName) {
        this.localAuthorityName = localAuthorityName;
    }

    public String getGeologicalType() {
        return geologicalType;
    }

    public void setGeologicalType(String geologicalType) {
        this.geologicalType = geologicalType;
    }

    public Double getHectare() {
        return hectare;
    }

    public void setHectare(Double hectare) {
        this.hectare = hectare;
    }

    public String getAlienationMethodName() {
        return alienationMethodName;
    }

    public void setAlienationMethodName(String alienationMethodName) {
        this.alienationMethodName = alienationMethodName;
    }


    public Map<Integer, String> getAlienationMethodSet() {
        return alienationMethodSet;
    }

    public void setAlienationMethodSet(Map<Integer, String> alienationMethodSet) {
        this.alienationMethodSet = alienationMethodSet;
    }

    public List<AlienationMethod> getAlienationMethods() {
        return alienationMethods;
    }

    public void setAlienationMethods(List<AlienationMethod> alienationMethods) {
        this.alienationMethods = alienationMethods;
    }

    public String[] getAlienationMethodSelectedList() {
        return alienationMethodSelectedList;
    }

    public void setAlienationMethodSelectedList(String[] alienationMethodSelectedList) {
        this.alienationMethodSelectedList = alienationMethodSelectedList;
    }

    public Map<Integer, String> getAmSelectedList() {
        return amSelectedList;
    }

    public void setAmSelectedList(Map<Integer, String> amSelectedList) {
        this.amSelectedList = amSelectedList;
    }

    public int getDsDivisionId() {
        return dsDivisionId;
    }

    public void setDsDivisionId(int dsDivisionId) {
        this.dsDivisionId = dsDivisionId;
    }

    public int getDistrictId() {
        return districtId;
    }

    public void setDistrictId(int districtId) {
        this.districtId = districtId;
    }

    public long[] getLandKachcheryList() {
        return landKachcheryList;
    }

    public void setLandKachcheryList(long[] landKachcheryList) {
        this.landKachcheryList = landKachcheryList;
    }

    public List<Land> getLandList() {
        return landList;
    }

    public void setLandList(List<Land> landList) {
        this.landList = landList;
    }

    public Kachchery getKachchery() {
        return kachchery;
    }

    public void setKachchery(Kachchery kachchery) {
        this.kachchery = kachchery;
    }

    public List<Long> getAssociationIdLandList() {
        return associationIdLandList;
    }

    public void setAssociationIdLandList(List<Long> associationIdLandList) {
        this.associationIdLandList = associationIdLandList;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public long[] getAmPermitList() {
        return amPermitList;
    }

    public void setAmPermitList(long[] amPermitList) {
        this.amPermitList = amPermitList;
    }

    public long[] getAmGrantList() {
        return amGrantList;
    }

    public void setAmGrantList(long[] amGrantList) {
        this.amGrantList = amGrantList;
    }

    public long[] getAmSTLList() {
        return amSTLList;
    }

    public void setAmSTLList(long[] amSTLList) {
        this.amSTLList = amSTLList;
    }

    public long[] getAmLTLList() {
        return amLTLList;
    }

    public void setAmLTLList(long[] amLTLList) {
        this.amLTLList = amLTLList;
    }

    public long[] getAmRDList() {
        return amRDList;
    }

    public void setAmRDList(long[] amRDList) {
        this.amRDList = amRDList;
    }

    public long[] getAmVOList() {
        return amVOList;
    }

    public void setAmVOList(long[] amVOList) {
        this.amVOList = amVOList;
    }

    public long[] getAmSPList() {
        return amSPList;
    }

    public void setAmSPList(long[] amSPList) {
        this.amSPList = amSPList;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public int getKachcheryMode() {
        return kachcheryMode;
    }

    public void setKachcheryMode(int kachcheryMode) {
        this.kachcheryMode = kachcheryMode;
    }

    public Map<Long, List<MapDetails>> getMapDetailMap() {
        return mapDetailMap;
    }

    public void setMapDetailMap(Map<Long, List<MapDetails>> mapDetailMap) {
        this.mapDetailMap = mapDetailMap;
    }

    public Map<Integer, String> getApprovedAssociatedAlienationMethodsList() {
        return approvedAssociatedAlienationMethodsList;
    }

    public void setApprovedAssociatedAlienationMethodsList(Map<Integer, String> approvedAssociatedAlienationMethodsList) {
        this.approvedAssociatedAlienationMethodsList = approvedAssociatedAlienationMethodsList;
    }
}
